package com.chain.qs.modules.biz.service;

import com.chain.qs.common.service.BaseService;
import com.chain.qs.common.utils.CastUtils;
import com.chain.qs.common.utils.EhCacheUtils;
import com.chain.qs.common.utils.StringUtils;
import com.chain.qs.modules.biz.dao.BasicInfoDao;
import com.chain.qs.modules.sys.utils.LogUtils;
import com.google.common.collect.Maps;
import org.apache.activemq.command.ActiveMQTopic;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
//@Transactional(readOnly = true)
public class BasicInfoService extends BaseService {

    @Resource(name = "basicInfoDao")
    protected BasicInfoDao dao;

    @Resource
    private WarningRecordService warningRecordService;

    @Resource
    private EquipmentItemWarningRuleService equipmentItemWarningRuleService;

    @Resource(name = "jmsTemplate")
    private JmsTemplate jmsTemplate;


    @Resource(name = "commandTopicDestination")
    private ActiveMQTopic commandTopicDestination;

    //查找存在的站组
    public HashMap<String, String> findAvailableSgrp() {
        if (EhCacheUtils.get(EhCacheUtils.SGRP_INFO_CACHE) == null) {
            EhCacheUtils.put(EhCacheUtils.SGRP_INFO_CACHE, extractResultList(dao.findAvailableSgrp()));
        }
        return CastUtils.convertToHashMapStringString(EhCacheUtils.get(EhCacheUtils.SGRP_INFO_CACHE));
    }
    public void refreshFindAvailableSgrp() {
        EhCacheUtils.put(EhCacheUtils.SGRP_INFO_CACHE, extractResultList(dao.findAvailableSgrp()));
    }

    //所有已配置站点设备状态
    public HashMap<String, String> findAvailableSgrpAndDeviceId() {
        return CastUtils.convertToHashMapStringString(extractResultList2(dao.findAvailableSgrpAndDeviceId()));
    }

    //所有配置的设备
    HashMap<String, String> findAvailableDevice() {
        if (EhCacheUtils.get(EhCacheUtils.DEVICE_INFO_CACHE) == null) {
            EhCacheUtils.put(EhCacheUtils.DEVICE_INFO_CACHE, extractResultList(dao.findAvailableDevice()));
        }
        return CastUtils.convertToHashMapStringString(EhCacheUtils.get(EhCacheUtils.DEVICE_INFO_CACHE));
    }
    public void refreshFindAvailableDevice() {
        EhCacheUtils.put(EhCacheUtils.DEVICE_INFO_CACHE, extractResultList(dao.findAvailableDevice()));
    }
    //所有的设备id及设备type
    public HashMap<String, String> findAvailableDeviceIdAndTypeId() {
        if (EhCacheUtils.get(EhCacheUtils.DEVICE_ID_TYPE_ID_INFO_CACHE) == null) {
            EhCacheUtils.put(EhCacheUtils.DEVICE_ID_TYPE_ID_INFO_CACHE, extractResultList(dao.findAvailableDeviceIdAndTypeId()));
        }
        return CastUtils.convertToHashMapStringString(EhCacheUtils.get(EhCacheUtils.DEVICE_ID_TYPE_ID_INFO_CACHE));
    }
    public void refreshFindAvailableDeviceIdAndTypeId() {
        EhCacheUtils.put(EhCacheUtils.DEVICE_ID_TYPE_ID_INFO_CACHE, extractResultList(dao.findAvailableDeviceIdAndTypeId()));
    }
    //所有的设备的标识
    public HashMap<String, String> findAvailableDeviceIdKeyword() {
        if (EhCacheUtils.get(EhCacheUtils.DEVICE_ID_KEYWORD_INFO_CACHE) == null) {
            EhCacheUtils.put(EhCacheUtils.DEVICE_ID_KEYWORD_INFO_CACHE, extractResultList(dao.findAvailableDeviceIdKeyword()));
        }
        return CastUtils.convertToHashMapStringString(EhCacheUtils.get(EhCacheUtils.DEVICE_ID_KEYWORD_INFO_CACHE));
    }
    public void refreshFindAvailableDeviceIdKeyword() {
        EhCacheUtils.put(EhCacheUtils.DEVICE_ID_KEYWORD_INFO_CACHE, extractResultList(dao.findAvailableDeviceIdKeyword()));
    }
    //设备参数id及对应参数名
    public HashMap<String, String> findAvailableParamIdName() {
        if (EhCacheUtils.get(EhCacheUtils.PARAM_ID_NAME_INFO_CACHE) == null) {
            EhCacheUtils.put(EhCacheUtils.PARAM_ID_NAME_INFO_CACHE, extractResultList(dao.findAvailableParamIdName()));
        }
        return CastUtils.convertToHashMapStringString(EhCacheUtils.get(EhCacheUtils.PARAM_ID_NAME_INFO_CACHE));
    }
    public void refreshFindAvailableParamIdName() {
        EhCacheUtils.put(EhCacheUtils.PARAM_ID_NAME_INFO_CACHE, extractResultList(dao.findAvailableParamIdName()));
    }
    //设备参数属性 kid ,equip_type_id ,id
    public HashMap<String, String> findAvailableParam() {
        if (EhCacheUtils.get(EhCacheUtils.PARAM_KID_EQUIP_ID_AND_ID_INFO_CACHE) == null) {
            EhCacheUtils.put(EhCacheUtils.PARAM_KID_EQUIP_ID_AND_ID_INFO_CACHE, extractResultListThreeItems(dao.findAvailableParam()));
        }
        return CastUtils.convertToHashMapStringString(EhCacheUtils.get(EhCacheUtils.PARAM_KID_EQUIP_ID_AND_ID_INFO_CACHE));
    }
    public void refreshFindAvailableParam() {
        EhCacheUtils.put(EhCacheUtils.PARAM_KID_EQUIP_ID_AND_ID_INFO_CACHE, extractResultListThreeItems(dao.findAvailableParam()));
    }
    //已经配置的设备的id对应的kid
    public HashMap<String, String> findAvailableDeviceIdAndEquipKid() {
        if (EhCacheUtils.get(EhCacheUtils.DEVICE_ID_EQUIP_KID_INFO_CACHE) == null) {
            EhCacheUtils.put(EhCacheUtils.DEVICE_ID_EQUIP_KID_INFO_CACHE, extractResultList(dao.findAvailableDeviceIdAndEquipKid()));
        }
        return CastUtils.convertToHashMapStringString(EhCacheUtils.get(EhCacheUtils.DEVICE_ID_EQUIP_KID_INFO_CACHE));
    }
    public void refreshFindAvailableDeviceIdAndEquipKid() {
        EhCacheUtils.put(EhCacheUtils.DEVICE_ID_EQUIP_KID_INFO_CACHE, extractResultList(dao.findAvailableDeviceIdAndEquipKid()));
    }
    //存储所有触发的规则
    public HashMap<String, Map<String, String>> warningRuleMapInfoCache() {
        if (EhCacheUtils.get(EhCacheUtils.WARNING_RULE_MAP_INFO_CACHE) == null) {
            refreshWarningRuleMapInfoCache();
        }
        return CastUtils.convertToDoubleHashMapStringString(EhCacheUtils.get(EhCacheUtils.WARNING_RULE_MAP_INFO_CACHE));
    }
    public void refreshWarningRuleMapInfoCache() {
        EhCacheUtils.put(EhCacheUtils.WARNING_RULE_MAP_INFO_CACHE, equipmentItemWarningRuleService.warningRuleMap());
    }
    //存储所有触发的规则 存储方式不一样
    public HashMap<String, Map<String, Map<String, Map<String, Map<String, String>>>>> warningRecordMapInfoCache() {
        if (EhCacheUtils.get(EhCacheUtils.WARNING_RECORD_MAP_INFO_CACHE) == null) {
            EhCacheUtils.put(EhCacheUtils.WARNING_RECORD_MAP_INFO_CACHE, warningRecordService.warningRecordMap());
        }
        return CastUtils.convertToFiveHashMapStringString(EhCacheUtils.get(EhCacheUtils.WARNING_RECORD_MAP_INFO_CACHE));
    }
    public void refreshWarningRecordMapInfoCache() {
        EhCacheUtils.put(EhCacheUtils.WARNING_RECORD_MAP_INFO_CACHE, warningRecordService.warningRecordMap());
    }

//    public HashMap<String, String> findAvailableOffice() {
//        if (EhCacheUtils.get(EhCacheUtils.OFFICE_INFO_CACHE) == null) {
//            EhCacheUtils.put(EhCacheUtils.OFFICE_INFO_CACHE, extractResultList(dao.findAvailableOffice()));
//        }
//        return CastUtils.convertToHashMapStringString(EhCacheUtils.get(EhCacheUtils.OFFICE_INFO_CACHE));
//    }


    //对获取的数据进行处理; 两列数据时的处理方法
    private HashMap<String, String> extractResultList(List<HashMap<String, String>> list) {
        HashMap<String, String> hm = Maps.newHashMap();
        for (HashMap<String, String> curMap : list) {
            hm.put(curMap.get("id"), curMap.get("name"));
        }
        return hm;
    }

    //对获取的数据进行处理; 三列数据时的处理方法
    private HashMap<String, String> extractResultListThreeItems(List<HashMap<String, String>> list) {
        HashMap<String, String> hm = Maps.newHashMap();
        for (HashMap<String, String> curMap : list) {
            hm.put(curMap.get("one") + "@" + curMap.get("two"), curMap.get("three"));
        }
        return hm;
    }
    //对获取的数据进行处理; 特殊的处理方法——总共四列数据：officeCode grp device1 device2，device2作为判断列，
    // 前三列按照 officeCode,{grp,{{device1:"on"),{device2:"off"),{device3:"on")...}}  进行存储
    private HashMap<String, Object> extractResultList2(List<HashMap<String, String>> list) {
        HashMap<String, Object> maps = Maps.newHashMap();

        for (HashMap<String, String> curMap : list) {
            //每次重置con
            HashMap<String, Object> con = Maps.newHashMap();
                        //先对设备进行判断是否断线  {dKey:"on"}
            if((curMap.size() == 3)){
                con.put(String.valueOf(curMap.get("three")),"on");
            }else if((curMap.size() == 4)){
                con.put(String.valueOf(curMap.get("three")),"off");
            }
//            con.put(String.valueOf(curMap.get("three")),"on"); //临时都为on 前台都显示
            //判断是否存在officeCode 不存在 建立
            if (!maps.containsKey(String.valueOf(curMap.get("one")))) {
                maps.put(String.valueOf(curMap.get("one")), new HashMap<>());

            }
            //判断是否存在officeCode下的grp  不存在 建立
            if (!((Map) maps.get(String.valueOf(curMap.get("one")))).containsKey(String.valueOf(curMap.get("two")))) {
                ((Map) maps.get(String.valueOf(curMap.get("one")))).put(String.valueOf(curMap.get("two")), new ArrayList<>());
            }
            //找到对应的officecode  sgrp 进行添加dkey  con需要重置
            ((List)(((Map) maps.get(String.valueOf(curMap.get("one")))).get(String.valueOf(curMap.get("two"))))).add(con);

        }
        return maps;
       //maps:   {officeCode,{group,{{device1:"on"),{device2:"off"),{device3:"on")...}}
    }

    public void sendCMDSaveLog(HttpServletRequest request, String device, String cmd, Exception ex) {
        LogUtils.saveLog4OnOff(request, ex, findAvailableDevice().get(device) + "-" + CMDTras2Name(cmd));
    }

    private String CMDTras2Name(String cmd) {
        String resultStr = "指令不明确!";
        switch (cmd) {
            case "shutdown":
                resultStr = "关机";
                break;
            case "startup":
                resultStr = "开机";
                break;
        }
        return resultStr;
    }
    //获取告警信息
    public Map<String, Map<String, List<Map<String, String>>>> getExistWarningMap() {
        if (EhCacheUtils.get(EhCacheUtils.NOT_RECOVERY_WARNING_RECORD_RULE_MAP_INFO_CACHE) == null) {
            EhCacheUtils.put(EhCacheUtils.NOT_RECOVERY_WARNING_RECORD_RULE_MAP_INFO_CACHE, warningRecordService.getExistRuleMap());
        }
        return CastUtils.convertToDoubleHashMapListStringString(EhCacheUtils.get(EhCacheUtils.NOT_RECOVERY_WARNING_RECORD_RULE_MAP_INFO_CACHE));
    }
    public void refreshGetExistWarningMap() {
        EhCacheUtils.put(EhCacheUtils.NOT_RECOVERY_WARNING_RECORD_RULE_MAP_INFO_CACHE, warningRecordService.getExistRuleMap());
    }


    HashMap<String, String> findGradeFourAvailableOffice() {
        if (EhCacheUtils.get(EhCacheUtils.GRADE_FOUR_OFFICE_INFO_CACHE) == null) {
            EhCacheUtils.put(EhCacheUtils.GRADE_FOUR_OFFICE_INFO_CACHE, extractResultList(dao.findGradeFourAvailableOffice()));
        }
        return CastUtils.convertToHashMapStringString(EhCacheUtils.get(EhCacheUtils.GRADE_FOUR_OFFICE_INFO_CACHE));
    }
    public void refreshFindGradeFourAvailableOffice() {
        EhCacheUtils.put(EhCacheUtils.GRADE_FOUR_OFFICE_INFO_CACHE, extractResultList(dao.findGradeFourAvailableOffice()));
    }

    /**
     * 设备指令发送
     * @param request
     * @param stationCode
     * @param groupId
     * @param device
     * @param cmd
     * @param value
     * @return
     */
    public String sendCMD(HttpServletRequest request, String stationCode ,String groupId ,String device, String cmd ,String value) {
        Exception ex = null;
        String flag = "true";
        try {
            if(StringUtils.isNoneBlank(stationCode) &&StringUtils.isNoneBlank(groupId) &&StringUtils.isNoneBlank(device) && StringUtils.isNoneBlank(cmd)){
                this.jmsTemplate.convertAndSend(commandTopicDestination, stationCode+"@"+groupId+"@"+device+"#"+cmd+"@"+value);
            }else{
                throw new IllegalArgumentException();
            }
        } catch (Exception e) {
            ex = e;
            e.printStackTrace();
            flag = "false";
        } finally {
            sendCMDSaveLog(request, device, cmd, ex);
            return flag;
        }
    }
}